<template>
  <div class="table-page">
    <CommonTable
        ref="tableRef"
        :columns="tableColumns"
        :config="tableConfig"
        :api="apiConfig"
        @add="handleAdd"
        @edit="handleEdit"
        @selection-change="handleSelectionChange"
    >
      <!-- 自定义状态列 -->
      <template #status="{ row }">
        <el-tag :type="row.isDraft ? 'warning' : 'success'">
          {{ row.isDraft ? '草稿' : '已保存' }}
        </el-tag>
      </template>

      <!-- 自定义字段数量列 -->
      <template #columnCount="{ row }">
        {{ row.columns?.length || 0 }}
      </template>

      <!-- 自定义操作列 -->
      <template #actions="{ row }">
        <el-button-group>
          <el-button type="primary" size="small" @click="handleEdit(row)">
            编辑
          </el-button>
          <el-button type="primary" size="small" @click="handleDelete(row)">
            删除
          </el-button>
          <el-button type="primary" size="small" @click="previewSql(row)">
            SQL预览
          </el-button>
          <el-button type="success" size="small" @click="createTable(row)">
            创建表
          </el-button>
          <el-button type="info" size="small" @click="previewCode(row)">
            代码预览
          </el-button>
          <el-button type="warning" size="small" @click="downloadTableCode(row)">
            下载代码
          </el-button>
          <el-button type="danger" size="small" @click="syncTableStructure(row)">
            同步结构
          </el-button>
        </el-button-group>
      </template>
    </CommonTable>

    <!-- 表配置表单弹窗 -->
    <CommonForm
        v-model:visible="showForm"
        :config="{
          size: '80%'
        }"
        :fields="formFields"
        :data="currentTable"
        :title="isEdit ? '编辑表配置' : '新建表配置'"
        @submit="handleFormSubmit"
        @close="handleFormClose"
    />

    <!-- SQL预览对话框 -->
    <el-dialog v-model="sqlPreviewVisible" title="SQL预览" width="80%" top="5vh">
      <CodeHighlight :code="sqlPreviewContent" language="sql" />
      <template #footer>
        <el-button @click="sqlPreviewVisible = false">关闭</el-button>
        <el-button type="primary" @click="copySqlCode">复制SQL</el-button>
        <el-button type="success" @click="downloadSql">下载SQL</el-button>
      </template>
    </el-dialog>

    <!-- 代码预览对话框 -->
    <el-dialog v-model="codePreviewVisible" title="代码预览" width="80%" top="5vh">
      <el-tabs v-model="activeTab">
        <el-tab-pane label="实体类" name="entity">
          <CodeHighlight :code="generatedCode.entity" language="java" />
        </el-tab-pane>
        <el-tab-pane label="DTO" name="dto">
          <CodeHighlight :code="generatedCode.dto" language="java" />
        </el-tab-pane>
        <el-tab-pane label="Mapper" name="mapper">
          <CodeHighlight :code="generatedCode.mapper" language="java" />
        </el-tab-pane>
        <el-tab-pane label="Service" name="service">
          <CodeHighlight :code="generatedCode.service" language="java" />
        </el-tab-pane>
        <el-tab-pane label="ServiceImpl" name="serviceImpl">
          <CodeHighlight :code="generatedCode.serviceImpl" language="java" />
        </el-tab-pane>
        <el-tab-pane label="Controller" name="controller">
          <CodeHighlight :code="generatedCode.controller" language="java" />
        </el-tab-pane>
      </el-tabs>
      <template #footer>
        <el-button @click="codePreviewVisible = false">关闭</el-button>
        <el-button type="primary" @click="copyAllCode">复制所有代码</el-button>
        <el-button type="success" @click="downloadAllCode">下载代码</el-button>
      </template>
    </el-dialog>

    <!-- 从数据库导入表对话框 -->
    <el-dialog v-model="importDialogVisible" title="从数据库导入表" width="60%">
      <el-form :model="importForm" label-width="100px">
        <el-form-item label="数据源" required>
          <el-select
              v-model="importForm.datasourceId"
              placeholder="请选择数据源"
              @change="loadDatabaseTables"
              style="width: 100%"
          >
            <el-option
                v-for="ds in datasources"
                :key="ds.id"
                :label="ds.name"
                :value="ds.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="选择表" required>
          <el-table
              border
              :data="databaseTables"
              @selection-change="handleImportTableSelection"
              max-height="400"
              v-loading="loadingTables"
          >
            <el-table-column type="selection" width="55" />
            <el-table-column prop="tableName" label="表名" width="200" />
            <el-table-column prop="tableComment" label="表注释" />
            <el-table-column label="状态" width="100">
              <template #default="{ row }">
                <el-tag v-if="isTableImported(row.tableName)" type="success">已导入</el-tag>
                <el-tag v-else type="info">未导入</el-tag>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="importDialogVisible = false">取消</el-button>
        <el-button
            type="primary"
            @click="importSelectedTables"
            :disabled="selectedImportTables.length === 0"
            :loading="importing"
        >
          导入选中的表
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {computed, onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import CommonTable from '@/components/base/CommonTable/index.vue'
import CommonForm from '@/components/base/CommonForm/index.vue'
import CodeHighlight from '@/components/ui/CodeHighlight.vue'
import {
  codegenApi,
  type CodegenTableDTO,
  type ColumnInfo,
  datasourceApi,
  type DatasourceDTO,
  type TableInfo
} from '@/api/codegen'
import {downloadFile} from '@/utils/download'
import {getApiConfig, getFormFields, getTableColumns, getTableConfig, TableApis} from './index'

// 页面数据
const tableRef = ref()
const isEdit = ref(false)
const currentTable = ref<CodegenTableDTO | null>(null)
const showForm = ref(false)
const selectedRows = ref<CodegenTableDTO[]>([])

// 数据源相关
const datasources = ref<DatasourceDTO[]>([])

// 预览相关
const sqlPreviewVisible = ref(false)
const sqlPreviewContent = ref('')
const codePreviewVisible = ref(false)
const activeTab = ref('entity')
const generatedCode = ref({
  entity: '',
  mapper: '',
  service: '',
  controller: '',
  dto: '',
  serviceImpl: ''
})

// 导入相关数据
const importDialogVisible = ref(false)
const databaseTables = ref<TableInfo[]>([])
const selectedImportTables = ref<TableInfo[]>([])
const loadingTables = ref(false)
const importing = ref(false)
const importForm = reactive({
  datasourceId: undefined as string | undefined
})

// 表单字段配置
const formFields = computed(() => {
  const datasourceOptions = datasources.value.map(ds => ({
    label: ds.name,
    value: ds.id
  }))
  return getFormFields(isEdit.value, datasourceOptions)
})

// 表格列配置
const tableColumns = computed(() => getTableColumns())

// 表格配置
const tableConfig = computed(() => ({
  ...getTableConfig(),
  // 添加自定义头部操作按钮
  customHeaderActions: [
    {
      text: '从数据库导入',
      type: 'info',
      icon: 'Download',
      handler: showImportDialog
    }
  ]
}))

// API配置
const apiConfig = computed(() => getApiConfig())

// 新增表配置
const handleAdd = () => {
  isEdit.value = false
  currentTable.value = {
    datasourceId: '',
    tableName: '',
    tableComment: '',
    entityName: '',
    packageName: 'com.big',
    generatePath: '/tmp/codegen',
    author: 'wzh',
    columns: [
      {
        columnName: 'id',
        columnType: 'BIGINT',
        columnLength: 20,
        columnScale: 0,
        columnComment: '主键ID',
        isPrimaryKey: true,
        isAutoIncrement: false,
        isNullable: false,
        defaultValue: '',
        javaFieldName: 'id',
        javaFieldType: 'String',
        showInList: true,
        showInForm: true,
        showInQuery: false,
        queryType: 'EQ',
        formType: 'input',
        onUpdateCurrentTimestamp: false,
        extra: ''
      }
    ],
    generateController: true,
    generateService: true,
    generateMapper: true,
    generateXml: true
  }
  showForm.value = true
}

// 编辑表配置
const handleEdit = (row: CodegenTableDTO) => {
  isEdit.value = true
  currentTable.value = { ...row }
  showForm.value = true
}

const handleDelete = async (row: CodegenTableDTO) => {
  try {
    await ElMessageBox.confirm(
        `确定要删除表 "${row.tableName}" 吗？`,
        '删除确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    await TableApis.deleteTableConfig(row.id!)
    ElMessage.success('删除成功')
    tableRef.value?.refresh()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }
}

// 选择变化处理
const handleSelectionChange = (selection: CodegenTableDTO[]) => {
  selectedRows.value = selection
}

// 表单提交处理
const handleFormSubmit = async (data: CodegenTableDTO) => {
  try {
    data.columnsConfig = JSON.stringify(data.columns)
    if (isEdit.value && currentTable.value) {
      // 编辑表配置
      // 将columns转为 json
      await TableApis.updateTableConfig(data)
      ElMessage.success('表配置更新成功')
    } else {
      // 新增表配置
      await TableApis.createTableConfig(data)
      ElMessage.success('表配置创建成功')
    }

    showForm.value = false
    tableRef.value?.refresh()
  } catch (error) {
    console.error('保存表配置失败:', error)
    ElMessage.error('保存表配置失败')
  }
}

// 表单关闭处理
const handleFormClose = () => {
  showForm.value = false
}

// SQL预览
const previewSql = async (table: CodegenTableDTO) => {
  try {
    const sqlContent = await codegenApi.generateSql(table)
    sqlPreviewContent.value = sqlContent
    sqlPreviewVisible.value = true
  } catch (error: any) {
    ElMessage.error(error.message || 'SQL预览失败')
  }
}

// 创建表到数据库
const createTable = async (table: CodegenTableDTO) => {
  try {
    await ElMessageBox.confirm(
        `确认在数据库中创建表 "${table.tableName}" 吗？`,
        '创建表确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    await codegenApi.createTable(table)
    ElMessage.success('表创建成功')
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(error.message || '创建表失败')
    }
  }
}

// 代码预览
const previewCode = async (table: CodegenTableDTO) => {
  try {
    const [entityRes, mapperRes, serviceRes, controllerRes, dtoRes, serviceImplRes] = await Promise.all([
      codegenApi.generateEntity(table),
      codegenApi.generateMapper(table),
      codegenApi.generateServiceCode(table),
      codegenApi.generateController(table),
      codegenApi.generateDTO(table),
      codegenApi.generateServiceImpl(table)
    ])

    generatedCode.value = {
      entity: entityRes,
      mapper: mapperRes,
      service: serviceRes,
      controller: controllerRes,
      dto: dtoRes,
      serviceImpl: serviceImplRes
    }

    codePreviewVisible.value = true
  } catch (error: any) {
    ElMessage.error(error.message || '代码预览失败')
  }
}

// 下载表代码
const downloadTableCode = async (table: CodegenTableDTO) => {
  try {
    const response = await codegenApi.downloadTable(table)
    downloadFile(response, `${table.entityName}.zip`)
    ElMessage.success('下载成功')
  } catch (error: any) {
    ElMessage.error(error.message || '下载失败')
  }
}

// 同步表结构
const syncTableStructure = async (table: CodegenTableDTO) => {
  try {
    await ElMessageBox.confirm(
        '确认同步表结构？这将从数据库获取最新的字段信息并更新当前配置。',
        '同步确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    await codegenApi.syncTableStructure(table.datasourceId, table.id)
    tableRef.value?.refresh()
    ElMessage.success('表结构同步成功')
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(error.message || '同步表结构失败')
    }
  }
}

// 复制SQL代码
const copySqlCode = async () => {
  try {
    await navigator.clipboard.writeText(sqlPreviewContent.value)
    ElMessage.success('SQL已复制到剪贴板')
  } catch (error: any) {
    ElMessage.error('复制失败')
  }
}

// 下载SQL
const downloadSql = () => {
  const blob = new Blob([sqlPreviewContent.value], { type: 'text/plain' })
  const url = window.URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = 'table.sql'
  link.click()
  window.URL.revokeObjectURL(url)
  ElMessage.success('SQL下载成功')
}

// 复制所有代码
const copyAllCode = async () => {
  try {
    const allCode = Object.entries(generatedCode.value)
        .map(([key, value]) => `// ${key.toUpperCase()}\n${value}`)
        .join('\n\n')
    await navigator.clipboard.writeText(allCode)
    ElMessage.success('代码已复制到剪贴板')
  } catch (error: any) {
    ElMessage.error('复制失败')
  }
}

// 下载所有代码
const downloadAllCode = () => {
  const allCode = Object.entries(generatedCode.value)
      .map(([key, value]) => `// ${key.toUpperCase()}\n${value}`)
      .join('\n\n')
  const blob = new Blob([allCode], { type: 'text/plain' })
  const url = window.URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = 'generated-code.txt'
  link.click()
  window.URL.revokeObjectURL(url)
  ElMessage.success('代码下载成功')
}

// 显示导入对话框
const showImportDialog = () => {
  importDialogVisible.value = true
  importForm.datasourceId = undefined
  databaseTables.value = []
  selectedImportTables.value = []
}

// 加载数据库表列表
const loadDatabaseTables = async () => {
  if (!importForm.datasourceId) {
    databaseTables.value = []
    return
  }

  loadingTables.value = true
  try {
    const tables = await codegenApi.getTables(importForm.datasourceId)
    databaseTables.value = tables || []
  } catch (error: any) {
    console.error('加载数据库表失败:', error)
    ElMessage.error(error.message || '加载数据库表失败')
    databaseTables.value = []
  } finally {
    loadingTables.value = false
  }
}

// 处理导入表选择
const handleImportTableSelection = (selection: TableInfo[]) => {
  selectedImportTables.value = selection
}

// 检查表是否已导入
const isTableImported = (tableName: string) => {
  // 这里需要从当前表格数据中检查
  // 由于使用了CommonTable，需要通过tableRef获取当前数据
  return false // 简化处理
}

// 导入选中的表
const importSelectedTables = async () => {
  if (selectedImportTables.value.length === 0) {
    ElMessage.warning('请选择要导入的表')
    return
  }

  importing.value = true
  try {
    const importPromises = selectedImportTables.value.map(table =>
        codegenApi.importTableFromDatabase(importForm.datasourceId!, table.tableName)
    )

    await Promise.all(importPromises)

    ElMessage.success(`成功导入 ${selectedImportTables.value.length} 个表`)
    importDialogVisible.value = false

    // 刷新表配置列表
    tableRef.value?.refresh()
  } catch (error: any) {
    console.error('导入表失败:', error)
    ElMessage.error(error.message || '导入表失败')
  } finally {
    importing.value = false
  }
}

// 加载数据源
const loadDatasources = async () => {
  try {
    const response = await datasourceApi.list()
    datasources.value = response || []
  } catch (error: any) {
    console.error('加载数据源失败:', error)
    ElMessage.error(error.message || '加载数据源失败')
    datasources.value = []
  }
}

// 初始化
onMounted(() => {
  loadDatasources()
})
</script>

<style scoped>
.table-page {
  height: 100%;
  background: #f5f5f5;
}

.el-button-group .el-button {
  margin: 0;
}

/* 确保代码预览区域的字体和滚动 */
pre {
  background-color: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
  overflow: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
}

code {
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
}

/* 调整标签页内容区域的内边距 */
:deep(.el-tabs__content) {
  padding: 15px;
}
</style>